<?php

declare(strict_types=1);

namespace App\Service;

use App\Constants\ErrorCode;
use App\Exception\BusinessException;
use App\Library\Common;
use App\Model\DadaShop;
use App\Model\data\CurrentShopData;
use App\Model\FlyGourmetMealConf;
use App\Model\FlyShop;
use App\Model\FlyShopOpenTime;
use App\Model\ReservedSeatsSet;
use Hyperf\DbConnection\Db;
use Hyperf\HttpServer\Contract\RequestInterface;
use Hyperf\Validation\Rule;
use Hyperf\Validation\ValidatorFactory;
use Hyperf\Di\Annotation\Inject;

/**
 * 店铺配置
 * Class ShopConfigService
 * @package App\Service
 */
class ShopConfigService extends BaseService
{

    const THIRD_OPEN = 1;
    const THIRD_CLOSE = 0;

    /**
     * @Inject
     * @var DadaService
     */
    private $dada;

    /**
     * @Inject
     * @var FlyShopService
     */
    private $shop;

    /**
     * @Inject
     * @var ShopDeliveryConfigService
     */
    private $deliveryConfig;

    /**
     * @Inject
     * @var RequestInterface
     */
    private $request;

    /**
     * @Inject
     * @var ValidatorFactory
     */
    private $validator;

    /**
     * 验证配置参数
     * @param int $user_id
     * @return array
     */
    public function deliveryConfigValidator(int $user_id): array
    {
        $config_data = $this->request->inputs(['id', 'config_status', 'delivery_type',
            'local_third_status', 'locate_point', 'locate_remark', 'point_lat', 'point_lng', 'start_time',
            'end_time', 'max_range', 'base_range', 'base_price', 'add_range', 'add_price']);

        if (empty($config_data['delivery_type'])) {
            throw new BusinessException(ErrorCode::NORMAL_ERROR, '参数错误');
        }
        $shop = $this->shop->getMyShop($user_id);
        if (empty($shop)) {
            throw new BusinessException(ErrorCode::NORMAL_ERROR, '非法操作');
        }
        // 修改信息
        $data_info = [
            'shop_id' => $shop['id']
        ];
        // 物流配置仅设置开关
        if ($config_data['delivery_type'] != 1) {
            $rule = [
                'config_status' => Rule::in([0, 1]),
                'delivery_type' => Rule::in([2, 3]),
                'start_time' => [
                    'required', 'integer', 'min:0', 'max:2359'
                ],
                'end_time' => [
                    'required', 'integer', 'min:0', 'max:2359'
                ],
                'locate_point' => ['string', 'max:255'],
                'locate_remark' => ['string', 'max:255'],
                'point_lat' => ['nullable', 'numeric', 'max:90', 'min:-90'],
                'point_lng' => ['nullable', 'numeric', 'max:180', 'min:-180']
            ];
            if ($config_data['delivery_type'] == 3) {
                $rule['local_third_status'] = [
                    Rule::in([0, 1])
                ];
                $rule['max_range'] = $rule['base_range'] = $rule['add_range'] = ['numeric', 'min:0'];
                $rule['base_price'] = $rule['add_price'] = ['numeric', 'min:0'];
                $data_info['local_third_status'] = $config_data['local_third_status'] ?? 0;
                $data_info['max_range'] = $config_data['max_range'];   // 最大配送范围
                $data_info['base_range'] = $config_data['base_range']; // 基础配送范围
                $data_info['base_price'] = $config_data['base_price']; // 基础配送费
                $data_info['add_range'] = empty($config_data['add_range']) ? 0 : $config_data['add_range'];// 每增加距离
                $data_info['add_price'] = empty($config_data['add_price']) ? 0 : $config_data['add_price'];// 增加的费用
            }


            $res = $this->validator->make($config_data, $rule);
            if ($res->fails()) {
                throw new BusinessException(ErrorCode::NORMAL_ERROR, $res->errors()->first());
            }
            // 如果未传经纬度根据定位地址获取经纬度

            $data_info['locate_point'] = $config_data['locate_point'];
            $data_info['point_lng'] = $config_data['point_lng'] ?? 0;
            $data_info['point_lat'] = $config_data['point_lat'] ?? 0;
            if (empty($config_data['point_lat']) || empty($config_data['point_lng'])) {
                $locate = Common::getAddressLocation($data_info['locate_point']);
                $data_info['point_lat'] = $locate['lat'] ?? 0;
                $data_info['point_lng'] = $locate['lng'] ?? 0;
            }
            // 开启同城第三方配送
            if ($config_data['delivery_type'] == ShopDeliveryConfigService::TYPE_LOCAL && !empty($config_data['local_third_status'])) {
                $res = $this->setThirdConfig($shop['id'], $config_data['locate_point'], $data_info['point_lat'], $data_info['point_lng'], self::THIRD_OPEN);
                if (!$res) {
                    throw new BusinessException(ErrorCode::NORMAL_ERROR, '该区域暂不支持第三方配送');
                }
            }
            if ($config_data['start_time'] > $config_data['end_time'] || !Common::integerTimeCheck($config_data['start_time']) || !Common::integerTimeCheck($config_data['end_time'])) {
                throw new BusinessException(ErrorCode::NORMAL_ERROR, '时间设置错误');
            }
            $data_info['config_status'] = $config_data['config_status'];
            $data_info['delivery_type'] = $config_data['delivery_type'];
            $data_info['start_time'] = $config_data['start_time'];
            $data_info['end_time'] = $config_data['end_time'];
            $data_info['locate_remark'] = $config_data['locate_remark'];

        } else {
            $data_info['delivery_type'] = 1;
            $data_info['config_status'] = $config_data['config_status'];
        }

        return $data_info;
    }

    /**
     * 检测并开启第三方配送
     * @param int $user_id
     * @param string $locate_point
     * @param float $lat
     * @param float $lng
     * @param int $act
     * @return bool
     */
    public function setThirdConfig(int $user_id, string $locate_point, float $lat, float $lng, int $act): bool
    {
        $shop = CurrentShopData::getData();
        if (empty($shop)) {
            throw new BusinessException(ErrorCode::NORMAL_ERROR, '店铺无效');
        }
        Db::beginTransaction();

        if ($act == 1) {
            // 未开通
            if ($this->dada->check_shop(intval($shop['id']))) {
                // 已开通-修改达达配置门店
                if (empty($lat) || empty($lng)) {
                    Db::rollBack();
                    throw new BusinessException(ErrorCode::NORMAL_ERROR, '缺少必填参数：经纬度');
                }
                $param = [
                    'id' => $shop['id'],
                    'station_address' => $locate_point,
                    'lng' => $lng,
                    'lat' => $lat,
                    'origin_shop_id' => $shop['id']
                ];
                // 更细店铺配送信息
                $res2 = $this->dada->edit_station(Common::filter_null($param));
                if ('fail' == $res2['status']) {
                    Db::rollBack();
                    return false;
                }
                // 开通门店
            } else {
                $param = [
                    "station_name" => $shop['shop_name'],
                    "city_name" => Common::address($locate_point)['city_name'] ?? "",
                    "area_name" => Common::address($locate_point)['region_name'] ?? "",
                    "station_address" => $locate_point,
                    "lng" => $lng,
                    "lat" => $lat,
                    "contact_name" => $shop['link_name'],
                    "phone" => $shop['phone'],
                    "origin_shop_id" => strval($shop['id']),
                    "business" => (int)($shop['shop_style'] == 1 ? 5 : 1)
                ];
                // 未开通-开通达达配置门店
                $res2 = $this->dada->open_station($param);
                // 未开通
                if ('fail' == $res2['status']) {
                    Db::rollBack();
                    return false;
                } else {
                    // 开通成功本地更新
                    $local_id = $this->dada->insert_station($param, $user_id);
                    if (!$local_id) {
                        Db::rollBack();
                        throw new BusinessException(ErrorCode::SERVER_ERROR, '操作失败');
                    }
                }
            }
        } else {
            // 关闭同城第三方配送
            make(DadaShop::class)
                ->where(['origin_shop_id' => $shop['id']])
                ->whereNull('deleted_at')
                ->update(['status' => 0]);
        }
        Db::commit();
        return true;
    }

    /**
     * 配送配置
     * @param array $data
     * @return int:配置ID或0:失败
     */
    public function setDeliveryConfig(array $data): int
    {
        return $this->deliveryConfig->setDeliveryConfig($data);
    }


    /**
     * 获取配送配置
     * @param int $user_id
     * @param int $type
     * @return array
     */
    public function getDeliveryConfig(int $user_id, int $type): array
    {
        $my_shop = $this->shop->getMyShop($user_id);
        if (empty($my_shop)) {
            return [];
        }
        return $this->deliveryConfig->getDeliveryConfig((int)$my_shop['id'], $type);
    }

    /**
     * 获取配送配置
     * @param int $user_id
     * @param int $status
     * @return array
     */
    public function getDeliveryConfigs(int $user_id, int $status = 0): array
    {
        $my_shop = $this->shop->getMyShop($user_id);
        if (empty($my_shop)) {
            return [];
        }
        return $this->deliveryConfig->getDeliveryConfigs((int)$my_shop['id'], $status);
    }

    /**
     * Notes:获取开业时间设置
     * @param int $shop_id
     * @return array
     * Date: 2022/7/22
     * Time:18:03
     * Auth: zdl
     */
    public function get_open_time(int $shop_id)
    {
        return FlyShopOpenTime::query()->where('shop_id',$shop_id)->orderBy('start_time','ASC')->select()->get()->toArray();
    }
    /**
     * Notes:获取开业时间设置
     * @param int $shop_id
     * @param array $open_time
     * @return array
     * Date: 2022/7/22
     * Time:18:03
     * Auth: zdl
     */
    public function set_open_time(int $shop_id,array $open_time)
    {
        $FlyShopOpenTime =  New FlyShopOpenTime();
        $check_res  = $this->check_time($open_time);
        if($check_res){
            $FlyShopOpenTime->where('shop_id',$shop_id)->delete();
            $time_arr = [];
            foreach ($open_time as $key=>$value){
                $time_arr[] = [
                    'start_time'=>$value['start_time'],
                    'end_time'=>$value['end_time'],
                    'shop_id'=>$shop_id,
                ];
            }
            if(count($time_arr)>0){
                $FlyShopOpenTime->insert($time_arr);
            }
            ReservedSeatsSet::query()
                ->where('shop_id',$shop_id)
                ->update(['open_time'=>json_encode($open_time)]);
            FlyGourmetMealConf::query()->where('shop_id', $shop_id)->update(['open_time'=>json_encode($open_time)]);
            return FlyShop::query()->where('id',$shop_id)->update(['open_time'=>json_encode($open_time)]);
        }else{
            return false;
        }

    }

    /**
     * 检查时间范围不可重复
     * @param array $open_time
     * @return bool
     */
    public function check_time(array $open_time)
    {
        if($open_time){
            $time = 0;
            foreach ($open_time as $key=>$value){
                if($key!=0){
                    if($value['start_time']>$value['end_time']){
                        return false;
                    }else{
                        $time = $value['end_time'];
                        if(!$value['end_time']>$time){
                            return false;
                        }
                    }
                }else{
                    if($value['start_time']>$value['end_time']){
                        return false;
                    }else{
                        $time = $value['end_time'];
                    }
                }
            }
            return true;
        }
    }

}